﻿/***************************************************************
 * 开发人员：网魂小兵@http://www.mozlite.com
 * 
 * 目标标本：4.0.30319.239
 * 
 * 最后修改：2011/11/10 13:34:17
 * ************************************************************/
namespace Mozlite.Common
{
    using System;
    using System.Linq;
    using System.Text;
    using System.Collections.Generic;
    using Mozlite.Cryptography;
    using Mozlite.Common.Configuration;
    using System.Web;
    using System.Collections;
    using System.Web.Security;

    internal class CachedUser
    {
        public DateTime Created;
        public User User;
    }

    /// <summary>
    /// 用户管理类。
    /// </summary>
    public class Users
    {
        private Users() { }

        #region gets
        /// <summary>
        /// 获取当前用户的登录名。
        /// </summary>
        /// <returns>返回当前用户的登录名。</returns>
        public static string GetLoggedOnUserName()
        {
            AppContext current = AppContext.Current;
            if (current.IsWebRequest && current.Context.User != null && current.Context.User.Identity.Name != string.Empty)
            {
                return current.Context.User.Identity.Name;
            }
            return "Anonymous";
        }
        /// <summary>
        /// 获取匿名用户。
        /// </summary>
        /// <param name="fromCache">是否从缓存里获取。</param>
        /// <returns>返回匿名用户对象。</returns>
        public static User GetAnonymousUser(bool fromCache = true)
        {
            User user = GetUser(-1, "Anonymous", null, false, true, fromCache);
            if (user == null)
            {
                user = new User() { UserName = "Anonymous", NickName = "Anonymous", AccountStatus = Common.AccountStatus.Approved, EncryptType = EncryptionAlgorithm.MD5, Password = Guid.NewGuid().ToString(), Email = "Anonymous@" + SiteSettings.Current.SiteDomain, IsAnonymous = true, CreateIP = "127.0.0.1", TimeZone = SiteSettings.Current.TimeZone };
                SecurityDataProvider.Current.CreateUser(user, true, Guid.Empty);
            }
            return user;
        }
        /// <summary>
        /// 获取当前HTTP上下文中匿名的唯一ID。
        /// </summary>
        /// <param name="context">当前HTTP上下文。</param>
        /// <returns>返回当前匿名用户的<see cref="T:System.Guid"/>对象。</returns>
        public static Guid GetAnonyousUserTrackingID(HttpContext context)
        {
            Guid guid;
            SiteSettings settings = SiteSettings.Current;
            HttpCookie cookie = context.Request.Cookies[settings.AnonymousCookieName];
            if (cookie == null || cookie.Value == null)
            {
                guid = Guid.NewGuid();
                cookie = new HttpCookie(settings.AnonymousCookieName);
            }
            else
            {
                try
                {
                    guid = new Guid(cookie.Value);
                }
                catch
                {
                    guid = Guid.NewGuid();
                }
            }
            cookie.Value = guid.ToString();
            cookie.Expires = DateTime.Now.AddMinutes((double)settings.AnonymousCookieExpiration);
            context.Response.Cookies.Add(cookie);
            return guid;
        }
        /// <summary>
        /// 移除匿名用户追踪。
        /// </summary>
        /// <param name="context">当前HTTP上下文。</param>
        /// <param name="cookieName">Cookie名称。</param>
        public static void RemoveAnonymousTracking(HttpContext context, string cookieName)
        {
            HttpCookie cookie = context.Request.Cookies[cookieName];
            if (cookie != null)
            {
                cookie.Expires = DateTime.Now.AddDays(-99.0);
                context.Response.Cookies.Add(cookie);
            }
        }
        /// <summary>
        /// 获取用户。
        /// </summary>
        /// <param name="isOnline">是否在线，如果在线将更新最后活动时间。</param>
        /// <returns>返回当前用户对象。</returns>
        public static User GetUser(bool isOnline = true)
        {
            return GetUser(-1, GetLoggedOnUserName(), null, isOnline);
        }
        /// <summary>
        /// 获取用户。
        /// </summary>
        /// <param name="userName">用户名称。</param>
        /// <returns>返回当前用户对象。</returns>
        public static User GetUser(string userName)
        {
            return GetUser(-1, userName);
        }
        /// <summary>
        /// 获取用户。
        /// </summary>
        /// <param name="userID">用户ID。</param>
        /// <param name="userName">用户名称。</param>
        /// <param name="email">用户电子邮件。</param>
        /// <param name="isOnline">是否在线，如果在线将更新最后活动时间。</param>
        /// <param name="isCacheable">是否缓存当前用户。</param>
        /// <param name="fromCache">是否从缓存里获取。</param>
        /// <returns>返回当前用户对象。</returns>
        public static User GetUser(int userID, string userName = null, string email = null, bool isOnline = false, bool isCacheable = true, bool fromCache = true)
        {
            string cacheKey = (userID > 0) ? UserKey(userID) : UserKey(userName ?? email);
            if (cacheKey == null)
                return null;
            User user;
            AppContext current = AppContext.Current;
            Hashtable hashtable = UserCache();
            if (fromCache)
            {
                user = current.Items[cacheKey] as User;
                if (user != null)
                    return user;
            }
            CachedUser cacheUser = null;
            if (fromCache)
            {
                cacheUser = hashtable[cacheKey] as CachedUser;
            }
            if (cacheUser != null)
            {
                if (isOnline)
                {
                    if (cacheUser.Created > DateTime.Now.AddSeconds(-30.0))
                    {
                        return cacheUser.User;
                    }
                    RemoveUserCache(cacheUser.User.UserID, cacheUser.User.UserName, cacheUser.User.Email);
                }
                else
                {
                    if (cacheUser.Created > DateTime.Now.AddMinutes(-180.0))
                    {
                        return cacheUser.User;
                    }
                    RemoveUserCache(cacheUser.User.UserID, cacheUser.User.UserName, cacheUser.User.Email);
                }
            }
            user = SecurityDataProvider.Current.GetUser(userID, userName, email, isOnline);
            if (user == null)
            {
                return null;
            }
            current.Items[UserKey(user.UserName)] = user;
            current.Items[UserKey(user.UserID)] = user;
            current.Items[UserKey(user.Email)] = user;
            if (isCacheable)
            {
                if (cacheUser == null)
                {
                    cacheUser = new CachedUser();
                }
                cacheUser.User = user;
                cacheUser.Created = DateTime.Now;
                hashtable[UserKey(user.UserName)] = cacheUser;
                hashtable[UserKey(user.UserID)] = cacheUser;
                hashtable[UserKey(user.Email)] = cacheUser;
            }
            return user;
        }
        /// <summary>
        /// 获取用户。
        /// </summary>
        /// <param name="email">电子邮件。</param>
        /// <returns>返回用户实例。</returns>
        public static User GetUserByEmail(string email)
        {
            return GetUser(-1, null, email);
        }

        private static string UserKey(string key)
        {
            if (key.IndexOf('@') != -1)
                return string.Format("User-EM:{0}", key);
            return string.Format("User-UN:{0}", key);
        }

        private static string UserKey(int UserID)
        {
            return string.Format("User-UID:{0}", UserID);
        }

        private static void RemoveUserCache(int userID, string userName, string email)
        {
            Hashtable hashtable = UserCache();
            hashtable[UserKey(userName)] = null;
            hashtable[UserKey(userID)] = null;
            hashtable[UserKey(email)] = null;
        }

        private static Hashtable UserCache()
        {
            return Caches.Get<Hashtable>("Users.UserLookupTable", CommonHelper.MinuteSeconds * 3, CommonHelper.MinuteSeconds * 3, () =>
            {
                return new Hashtable();
            });
        }
        /// <summary>
        /// 通过电子邮件获取用户ID。
        /// </summary>
        /// <param name="email">用户电子邮件。</param>
        /// <returns>返回用户ID。</returns>
        public static int GetUserIDByEmail(string email)
        {
            if (string.IsNullOrEmpty(email))
                return -1;
            return SecurityDataProvider.Current.GetUserIDByEmail(email);
        }
        /// <summary>
        /// 通过用户名获取用户ID。
        /// </summary>
        /// <param name="userName">用户名。</param>
        /// <returns>返回用户ID。</returns>
        public static int GetUserIDByUserName(string userName)
        {
            if (string.IsNullOrEmpty(userName))
                return -1;
            return SecurityDataProvider.Current.GetUserIDByUserName(userName);
        }
        /// <summary>
        /// 保存用户详细信息。
        /// </summary>
        /// <param name="user">用户实例对象。</param>
        /// <returns>返回创建用户状态。</returns>
        public static CreateUserStatus SaveProfile(User user)
        {
            CreateUserStatus status = SecurityDataProvider.Current.SaveProfile(user);
            if (status == CreateUserStatus.Updated)
            {
                RemoveUserCache(user.UserID, user.UserName, user.Email);
            }
            return status;
        }
        /// <summary>
        /// 将用户设置为跨站管理员。
        /// </summary>
        /// <param name="userID">用户ID。</param>
        /// <param name="isGlobalAdministrator">是否为跨站管理员。</param>
        /// <returns>返回是否成功。</returns>
        public static bool SetGlobalAdministrator(int userID, bool isGlobalAdministrator = true) {
            return SecurityDataProvider.Current.SetGlobalAdministrator(userID, isGlobalAdministrator);
        }
        #endregion

        #region create
        /// <summary>
        /// 编辑用户。
        /// </summary>
        /// <param name="user">用户实例对象。</param>
        /// <param name="ignoreDisallowNames">忽略禁用名称。</param>
        /// <returns>返回创建用户状态。</returns>
        public static CreateUserStatus EditUser(User user, bool ignoreDisallowNames = false)
        {
            User dbUser = GetUser(user.UserID);
            if (dbUser == null)
            {
                return CreateUserStatus.UnknownFailure;
            }

            if (!dbUser.UserName.IsMatched(user.UserName))
            {
                if (!SiteSettings.IsUserNameValid(user.UserName))
                    return CreateUserStatus.InvalidUserName;
                if (!ignoreDisallowNames && SiteSettings.IsDisallowed(user.UserName))
                    return CreateUserStatus.DisallowedUserName;
            }
            if (!string.IsNullOrEmpty(user.Password) && !SiteSettings.IsPasswordValid(user.Password))
                return CreateUserStatus.InvalidPassword;
            if (!user.Email.IsEmail())
                return CreateUserStatus.InvalidEmail;

            //Events.BeforeUser(user, ObjectState.Update);
            //一些属性拷贝
            user.PasswordSalt = dbUser.PasswordSalt;
            if (string.IsNullOrEmpty(user.Password))
                user.Password = dbUser.Password;
            else
            {
                string salt = user.PasswordSalt;
                user.Password = CommonHelper.Encrypt(user.Password, user.EncryptType, ref salt);
                user.LastPasswordChangedDate = DateTime.Now;
            }
            if (string.IsNullOrEmpty(user.PasswordAnswer))
                user.PasswordAnswer = dbUser.PasswordAnswer;
            else
            {
                string salt = user.PasswordSalt;
                user.PasswordAnswer = CommonHelper.Encrypt(user.PasswordAnswer, user.EncryptType, ref salt);
            }
            user.Merger(dbUser);

            try
            {
                CreateUserStatus status = SecurityDataProvider.Current.EditUser(user, SiteSettings.Default.UniqueEmail);
                if (status == CreateUserStatus.Updated)
                {
                    RemoveUserCache(user.UserID, user.UserName, user.Email);
                }
                //Events.AfterUser(user, ObjectState.Update);
                return status;
            }
            catch { }
            return CreateUserStatus.UnknownFailure;
        }
        /// <summary>
        /// 创建用户。
        /// </summary>
        /// <param name="user">当前用户对象。</param>
        /// <param name="publicKey">邀请注册的GUID。</param>
        /// <param name="ignoreDisallowNames">是否忽略禁用名称。</param>
        /// <returns>返回当前用户创建的状态信息。</returns>
        public static CreateUserStatus CreateUser(User user, string publicKey, bool ignoreDisallowNames = false)
        {
            if (!SiteSettings.IsUserNameValid(user.UserName))
                return CreateUserStatus.InvalidUserName;
            if (!ignoreDisallowNames && SiteSettings.IsDisallowed(user.UserName))
                return CreateUserStatus.DisallowedUserName;
            if (!SiteSettings.IsPasswordValid(user.Password))
                return CreateUserStatus.InvalidPassword;
            if (!user.Email.IsEmail())
                return CreateUserStatus.InvalidEmail;
            if (string.IsNullOrEmpty(user.NickName))
                user.NickName = user.UserName;
            string password = user.Password;

            var settings = SiteSettings.Default;
            User cusr = AppContext.Current.User;
            AccountActivation accountActivation = settings.AccountActivation;
            if (cusr.IsAdministrator)
            {
                accountActivation = AccountActivation.Automatic;
            }
            Guid key = Guid.Empty;
            if (settings.AccountActivation == AccountActivation.InvitationOnly)
            {
                if (string.IsNullOrEmpty(publicKey))
                    return CreateUserStatus.InvitationKeyNotNull;
                try
                {
                    key = new Guid(publicKey);
                }
                catch
                {
                    return CreateUserStatus.InvalidInvitationKey;
                }
            }
            //Events.BeforeUser(user, ObjectState.Create);
            try
            {
                string salt = null;
                user.Password = CommonHelper.Encrypt(user.Password, settings.EncryptType, ref salt);
                if (!string.IsNullOrEmpty(user.PasswordAnswer))
                    user.PasswordAnswer = CommonHelper.Encrypt(user.PasswordAnswer, settings.EncryptType, ref salt);
                user.EncryptType = settings.EncryptType;
                user.AccountStatus = accountActivation == AccountActivation.Automatic ? AccountStatus.Approved : AccountStatus.ApprovalPending;
                user.PasswordSalt = salt;
                if (user.CreateIP == null)
                {
                    user.CreateIP = AppContext.Current.Context.Request.UserHostAddress;
                }
                CreateUserStatus status = SecurityDataProvider.Current.CreateUser(user, settings.UniqueEmail, key);
                if (status == CreateUserStatus.Created)
                {
                    var configuration = UCenterApplication.Current.Configuration;
                    if (configuration.EnableDefaultRole)
                    {
                        Roles.AddRoles(user.UserID, configuration.DefaultRoleIDs);
                    }
                    //Events.AfterUser(user, ObjectState.Create);
                }
                else
                {
                    return status;
                }
            }
            catch
            {
                return CreateUserStatus.UnknownFailure;
            }
            if (settings.SendEmail)
            {
                switch (accountActivation)
                {
                    case AccountActivation.Automatic:
                    case AccountActivation.InvitationOnly:
                        Mails.UserCreated(user, password);
                        return CreateUserStatus.Created;

                    case AccountActivation.Email:
                        Mails.UserActivate(user, password);
                        return CreateUserStatus.EmailActivation;

                    case AccountActivation.AdminApproval:
                        Mails.UserAccountPending(user);
                        return CreateUserStatus.AdminApproval;
                }
            }
            return CreateUserStatus.Created;
        }
        #endregion

        #region security
        /// <summary>
        /// 验证用户密码。
        /// </summary>
        /// <param name="password">用户密码。</param>
        /// <param name="user">用户实例。</param>
        /// <returns>如果符合返回<c>true</c>，否则返回<c>false</c>。</returns>
        public static bool CheckPassword(string password, User user)
        {
            if (user.EncryptType <= EncryptionAlgorithm.SHA512)
                return CommonHelper.Encrypt(password, user.EncryptType).IsMatched(user.Password, false);
            return CommonHelper.Decrypt(user.Password, user.EncryptType, user.PasswordSalt).IsMatched(password, false);
        }
        /// <summary>
        /// 验证用户安全答案。
        /// </summary>
        /// <param name="answer">用户安全答案。</param>
        /// <param name="user">用户实例。</param>
        /// <returns>如果符合返回<c>true</c>，否则返回<c>false</c>。</returns>
        public static bool CheckAnswer(string answer, User user)
        {
            if (user.EncryptType <= EncryptionAlgorithm.SHA512)
                return string.Compare(CommonHelper.Encrypt(answer, user.EncryptType), user.PasswordAnswer, false) == 0;
            return string.Compare(CommonHelper.Decrypt(user.PasswordAnswer, user.EncryptType, user.PasswordSalt), answer, false) == 0;
        }
        /// <summary>
        /// 验证用户。
        /// </summary>
        /// <param name="mode">验证模式。</param>
        /// <param name="value">用户名称。</param>
        /// <param name="password">用户密码。</param>
        /// <returns>返回用户登录状态。</returns>
        public static LoginUserStatus ValidUser(ValidMode mode, string value, string password)
        {
            AppContext current = AppContext.Current;
            User user = null;
            if (mode == ValidMode.UserName)
                user = GetUser(value);
            else if (mode == ValidMode.UserID)
                user = GetUser(value.ToInt32());
            else
                user = GetUserByEmail(value);
            if (user == null)
                return LoginUserStatus.InvalidCredentials;
            if (user.AccountStatus == AccountStatus.ApprovalPending)
            {
                return LoginUserStatus.AccountPending;
            }
            if (user.AccountStatus == AccountStatus.Disapproved)
            {
                return LoginUserStatus.AccountDisapproved;
            }
            if (!CheckPassword(password, user))
            {
                Logs.Warn("Failed login for valid mode “" + mode + "” value " + value, "Security", EventID.Users); 
                SetValidFailure(user);
                return LoginUserStatus.InvalidCredentials;
            }
            var settings = SiteSettings.Default;
            if (!settings.EnableBannedUsersToLogin && user.IsLockedOut && DateTime.Now <= user.BannedUntil)
            {
                return LoginUserStatus.AccountBanned;
            }
            if (user.IsLockedOut && DateTime.Now > current.User.BannedUntil)
            {
                user.AccountStatus = AccountStatus.Approved;
                current.User.BannedUntil = DateTime.Now;
                SetAccountStatus(user.UserID, user.AccountStatus, user.LastLockoutDate, BannedReason.Other);
            }
            current.User = user;
            if (current.IsWebRequest)
            {
                RemoveAnonymousTracking(current.Context, settings.AnonymousCookieName);
            }
            //Events.UserValidated(user);
            return LoginUserStatus.Success;
        }
        /// <summary>
        /// 修改密码。
        /// </summary>
        /// <param name="userID">用户ID。</param>
        /// <param name="password">新用户密码。</param>
        public static void ChangePassword(int userID, string password)
        {
            if (string.IsNullOrEmpty(password))
                return;
            User user = GetUser(userID);
            if (user == null)
                return;
            string salt = user.PasswordSalt;
            password = CommonHelper.Encrypt(password, user.EncryptType, ref salt);
            SecurityDataProvider.Current.ChangePassword(userID, password);
        }
        /// <summary>
        /// 修改安全信息。
        /// </summary>
        /// <param name="userID">用户ID。</param>
        /// <param name="question">新用户问题。</param>
        /// <param name="answer">新用户答案。</param>
        public static void ChangeSecurityQuestionAndAnswer(int userID, string question, string answer)
        {
            if (string.IsNullOrEmpty(question) || string.IsNullOrEmpty(answer))
                return;
            User user = GetUser(userID);
            if (user == null)
                return;
            string salt = user.PasswordSalt;
            answer = CommonHelper.Encrypt(answer, user.EncryptType, ref salt);
            SecurityDataProvider.Current.ChangeSecurityQuestAndAnswer(userID, question, answer);
        }
        #endregion

        #region helper
        /// <summary>
        /// 写入登录Cookie，然后转向用户中心。
        /// </summary>
        /// <param name="autoLogin">是否保存登录。</param>
        public static void SignIn(bool autoLogin)
        {
            AppContext current = AppContext.Current;
            HttpCookie authCookie = FormsAuthentication.GetAuthCookie(current.User.UserName, autoLogin);
            current.User.GetUserCookie().WriteCookie(authCookie, 30, autoLogin);
        }
        /// <summary>
        /// 更新用户状态信息。
        /// </summary>
        /// <param name="userID">用户ID。</param>
        /// <param name="status">用户状态。</param>
        /// <returns>返回是否更新成功。</returns>
        public static bool SetAccountStatus(int userID, AccountStatus status)
        {
            return SecurityDataProvider.Current.SetAccountStatus(userID, status, DateTime.MinValue, BannedReason.Other);
        }
        /// <summary>
        /// 更新用户状态信息。
        /// </summary>
        /// <param name="userID">用户ID。</param>
        /// <param name="status">用户状态。</param>
        /// <param name="bannedUntil">禁用过期时间。</param>
        /// <param name="reason">禁用原因。</param>
        /// <returns>返回是否更新成功。</returns>
        public static bool SetAccountStatus(int userID, AccountStatus status, DateTime bannedUntil, BannedReason reason)
        {
            return SecurityDataProvider.Current.SetAccountStatus(userID, status, bannedUntil, reason);
        }
        /// <summary>
        /// 验证失败，设置验证状态。
        /// </summary>
        /// <param name="user">用户实例对象。</param>
        /// <returns>返回是否成功。</returns>
        public static bool SetValidFailure(User user)
        {
            if (user.FailedPasswordAttemptCount >= SiteSettings.Default.MaxFailedPasswordAttemptCount - 1)
            {
                user.AccountStatus = AccountStatus.Banned;
                user.BannedUntil = DateTime.Now.AddMinutes(SiteSettings.Default.FailedPasswordAttemptWindowTimeout);
                user.BannedReason = BannedReason.ValidFailuredTimeout;
            }
            return SecurityDataProvider.Current.SetValidFailure(user);
        }
        /// <summary>
        /// 检索用户。
        /// </summary>
        /// <param name="query">用户查询实例对象。</param>
        /// <param name="size">返回所有用户记录数。</param>
        /// <returns>返回用户列表。</returns>
        public static List<User> Search(UserQuery query, out int size)
        {
            return SecurityDataProvider.Current.Search(query, out size);
        }
        /// <summary>
        /// 删除用户。
        /// </summary>
        /// <param name="userIDs">用户ID，以“,”分割。</param>
        /// <returns>返回删除结果。</returns>
        public static bool DeleteUsers(string userIDs)
        {
            return SecurityDataProvider.Current.DeleteUsers(userIDs);
        }
        ///// <summary>
        ///// 获取激活用户验证的字符串。
        ///// </summary>
        ///// <param name="user">用户实例对象。</param>
        ///// <param name="token">临时标识码。</param>
        ///// <returns>返回激活账号的验证字符串。</returns>
        //public static string GetActiveUser(User user, Guid token)
        //{
        //    if (token == null || Guid.Empty == token)
        //    {
        //        token = TemporaryUserTokens.Create(user.UserID, TemporaryUserTokenType.ActiveUser, Globals.DaySeconds);
        //    }
        //    string valid = (user.UserName.Trim() + "234" + user.Password.Trim() + "#$%" + user.TimeZone + "RgfTE434Rt" + (user.Email ?? "").Trim() + "$%^" + user.EncryptType + "564" + user.CreateIP.Trim() + "fGR^%$45" + token.ToString()).ToLower();
        //    return CommonHelper.Encrypt(CommonHelper.Encrypt(valid, EncryptionAlgorithm.MD5), EncryptionAlgorithm.MD5);
        //}
        ///// <summary>
        ///// 验证激活用户。
        ///// </summary>
        ///// <param name="user">用户实例对象。</param>
        ///// <param name="value">验证的字符串。</param>
        ///// <returns>返回验证状态。</returns>
        //public static AccountActiveStatus ValidActive(User user, string value)
        //{
        //    if (user == null || user.AccountStatus != UserAccountStatus.ApprovalPending)
        //        return AccountActiveStatus.Error;
        //    Guid token = TemporaryUserTokens.GetToken(user.UserID, TemporaryUserTokenType.ActiveUser);
        //    if (token == null || token == Guid.Empty)
        //        return AccountActiveStatus.TimeOut;
        //    if (GetActiveUser(user, token).IsMatched(value) && SaveAccountStatus(user.UserID, UserAccountStatus.Approved))
        //    {
        //        user.AccountStatus = UserAccountStatus.Approved;
        //        return AccountActiveStatus.Success;
        //    }
        //    return AccountActiveStatus.Error;
        //}
        #endregion

        #region profiles
        private static readonly string profileCacheKey = "UserProfiles::{0}::UserID::{1}";

        private static string GetProfileKey(int userID, int settingsID)
        {
            return string.Format(profileCacheKey, settingsID, userID);
        }

        /// <summary>
        /// 获取用户档案。
        /// </summary>
        /// <param name="userID">用户ID。</param>
        /// <returns>返回用户档案实例对象。</returns>
        public static UserProfile GetProfile(int userID = -1)
        {
            if (userID == -1)
                userID = AppContext.Current.User.UserID;
            int settingsID = SiteSettings.Current.SettingsID;
            return Caches.Get<UserProfile>(GetProfileKey(userID, settingsID), Globals.MinuteSeconds * 3, Globals.MinuteSeconds * 3, () => { 
                var profile = SecurityDataProvider.Current.GetProfile(SiteSettings.Current.SettingsID, userID);
                if (profile == null)
                {
                    profile = new UserProfile();
                    SaveProfile(profile);
                }
                return profile;
            });
        }

        /// <summary>
        /// 保存用户档案。
        /// </summary>
        /// <param name="profile">用户档案实例对象。</param>
        /// <returns>返回执行结果。</returns>
        public static bool SaveProfile(UserProfile profile)
        {
            if (SecurityDataProvider.Current.SaveProfile(profile))
            {
                Caches.Remove(GetProfileKey(profile.UserID, profile.SettingsID));
                return true;
            }
            return false;
        }
        #endregion
    }
}